class_name CameraController
extends SpringArm3D

@onready var camera_3d: Camera3D = $Camera3D
@onready var player: CharacterBody3D = $".."
@onready var move_timer: Timer = $Timer

@export var rotate_y_max: float = 90
@export var rotate_y_min: float = 0
@export var rotate_speed: float = 1
@export var min_spring_length: float = 5
@export var max_spring_length: float = 30
@export var spring_target_length: float = 10

var is_player_control: bool = true
var mouse_axis: Vector2 = Vector2.ZERO

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	move_timer.timeout.connect(_on_move_timer_timeout)

func _process(delta: float) -> void:
	camera_3d.look_at(global_position)
	
	var axis_x: float = mouse_axis.y * delta
	var axis_y: float = -mouse_axis.x * delta

	if is_player_control:
		player.rotation_degrees.y += axis_y * rotate_speed
	else:
		rotation_degrees.y += axis_y * rotate_speed
	
	rotation_degrees.x += axis_x * rotate_speed

	rotation_degrees.x = clamp(rotation_degrees.x, rotate_y_min, rotate_y_max)
	rotation_degrees.y = normalize_degrees(rotation_degrees.y)
	player.rotation_degrees.y = normalize_degrees(player.rotation_degrees.y)

	if spring_length != spring_target_length:
		spring_length = lerp(spring_length, spring_target_length, 0.1)

func normalize_degrees(degrees: float) -> float:
	if degrees > 360:
		degrees -= 360
	elif degrees < 0:
		degrees += 360
	return degrees

func _on_move_timer_timeout() -> void:
	mouse_axis = Vector2.ZERO

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

	if event.is_action_pressed("toggle_mouse_capture"):
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

	if event.is_action("camera_not_control"):
		if event.is_action_pressed("camera_not_control"):
			is_player_control = false
		else:
			is_player_control = true
			rotation_degrees.y = 0
	
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_WHEEL_UP:
			spring_target_length = clamp(spring_length - 2, min_spring_length, max_spring_length)
		elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
			spring_target_length = clamp(spring_length + 2, min_spring_length, max_spring_length)

	if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
		mouse_axis = event.relative
		move_timer.start()
